package com.dylan.channel.v3;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.nio.channels.spi.SelectorProvider;
import java.nio.charset.StandardCharsets;
import java.util.Iterator;
import java.util.Set;
import java.util.logging.Logger;

/***
 * Description: Nio事件循环处理器
 * @Author: dylan
 * @Date: 2024/8/27 23:24
 */
public class NioEventLoop extends SingleThreadEventLoop{
    Logger logger = Logger.getLogger(NioEventLoop.class.getName());
    Selector selector;

    private Selector openSelector() {
        Selector wrapSelector = null;
        try {
            wrapSelector = SelectorProvider.provider().openSelector();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return wrapSelector;
    }

    public NioEventLoop() {
        selector=openSelector();
    }

    public void run() {
        for (; ; ) {
            try {
                int select = selector.select(3000);
                if (select > 0 || hasTask()) {
                    break;
                }
                processSelectKeys(selector.selectedKeys());
            } catch (IOException e) {
                throw new RuntimeException(e);
            } finally {
                runAllTask();
            }
        }
    }

    private void processSelectKeys(Set<SelectionKey> keys) {
        Iterator<SelectionKey> iterator = keys.iterator();
        while (iterator.hasNext()){
            SelectionKey key = iterator.next();
            iterator.remove();
            processSelectKey(key);
        }
    }

    private void processSelectKey(SelectionKey key) {
        try {
            if(key.isReadable()){
                SocketChannel channel = (SocketChannel) key.channel();
                ByteBuffer buffer = ByteBuffer.allocate(1024);
                int read = channel.read(buffer);
                if(read==-1){
                    channel.close();
                    key.cancel();
                    return;
                }
                buffer.flip();
                logger.info("接受到客户端发过来的消息:"+new String(buffer.array(), StandardCharsets.UTF_8));
            }
        } catch (IOException e) {
            e.printStackTrace();
            key.cancel();
        }
    }

    @Override
    protected Selector getSelect() {
        return this.selector;
    }
}